const {task, series, src, dest} = require('gulp')
const swig = require('gulp-swig')
const data = require('gulp-data')
const rename = require('gulp-rename')

const shell = require('gulp-shell').task

let config = null
const configFile = './config.json'

// [Neo] .TODO maybe need to change them
const projectName = 'pay'
const password = 'pay.Docker'
const domain = 'pay.jnaw.top'

const runSqlPrefix = 'docker exec -i ' + projectName + '_db_1 '
    + 'mysql -uroot -proot --default-character-set=utf8mb4 ' + projectName

const init = _ =
>
{
  return src('./templates/config.json')
  .pipe(swig({
    load_json: true,
    data: {
      project: projectName,
      password: password,
      domain: domain,
    }
  }))
  .pipe(rename(configFile))
  .pipe(dest('./'))
}

const prepare = done =
>
{
  if (!config) {
    require('fs').exists(configFile, exists = > {
      if(exists) {
        config = require(configFile)
        done()
      } else {
        init().on('finish', _ = > {
        config = require(configFile)
        done()
      }
  )
  }
  })
  } else {
    done()
  }
}

const generate = (tag, done) =
>
{
  if (null == config || null == config[tag]) {
    console.error('generate: null config')
    return
  }

  const target = config[tag]
  // [Neo] .TODO
  // console.log(target)
  return src(target.from)
  .pipe(data(config))
  .pipe(swig())
  .pipe(rename(target.name))
  .pipe(dest(target.dest))
  .on('finish', done)
  .on('err', done)
}

const genDocker = done =
>
generate('docker', done)
const genShCreate = done =
>
generate('sh-create', done)
const genShBye = done =
>
generate('sh-bye', done)
const genShAccTomcat = done =
>
generate('sh-acc-tomcat', done)
const genShDumps = done =
>
generate('sh-dumps', done)
const genShDeploy = done =
>
generate('sh-deploy', done)
const genShRefresh = done =
>
generate('sh-refresh', done)
const genNgServer = done =
>
generate('nginx-server', done)
const genNgHttp = done =
>
generate('nginx-http', done)
const genNgHttps = done =
>
generate('nginx-https', done)
const genSqlLockRoot = done =
>
generate('sql-lock-root', done)
const genSqlMCTable = done =
>
generate('sql-merge-charset-table', done)
const genSqlMCFields = done =
>
generate('sql-merge-charset-fields', done)
const genSqlMIPrepare = done =
>
generate('sql-merge-init-prepare', done)
const genSqlMI = done =
>
generate('sql-merge-init', done)
const exec = (cmd, done) =
>
shell(cmd).call().then(done).catch(done)
const execSqlFile = (file, done) =
>
exec(runSqlPrefix + ' < ' + file + ' > /tmp/out.sql', done)
// [Neo] .TODO
// exec('cat ' + file + ' && ' + runSqlPrefix + ' < ' + file + ' > /tmp/out.sql', done)

const execShell = done =
>
exec('sh /tmp/todo.sh', done)
// [Neo] .TODO
// const execShell = done => exec('cat /tmp/todo.sh && sh /tmp/todo.sh', done)
const execSql = done =
>
execSqlFile('/tmp/todo.sql', done)

const log = done =
>
exec('docker logs -f --tail 200 ' + projectName + '_web_1', done)

const execGenTodoSql = done =
>
exec(
    'cat /tmp/out.sql | sed \'1d\' > /tmp/db-todo.sql', done)
const execAppendTodoSql = done =
>
exec(
    'cat /tmp/out.sql | sed \'1d\' >> /tmp/db-todo.sql', done)
const execGenTmpDb = done =
>
exec(runSqlPrefix + '_tmp < db-init.sql', done)
const execTodoSql = done =
>
execSqlFile('/tmp/db-todo.sql', done)

task('init', init)
task('default', series(prepare, genDocker, genShCreate, execShell))

task('bye', series(prepare, genShBye, execShell))
task('acc-tomcat', series(prepare, genShAccTomcat, execShell))

task('nginx', series(prepare, genNgServer, genNgHttp, genNgHttps))
task('deploy', series(prepare, genShDeploy, execShell))

task('log', log)
task('refresh', series(prepare, genShRefresh, execShell, log))

task('dumps', series(prepare, genShDumps, execShell))
task('lock-root', series(prepare, genSqlLockRoot, execSql))

// ALTER DATABASE {{ project }} CHARACTER SET {{ db.charset }} COLLATE {{ db.collate }};
task('merge-charset', series(prepare,
    genSqlMCTable, execSql, execGenTodoSql,
    genSqlMCFields, execSql, execAppendTodoSql,
    execTodoSql))

task('merge-init', series(prepare,
    genSqlMIPrepare, execSql, execGenTmpDb,
    genSqlMI, execSql, execGenTodoSql,
    execTodoSql,
    genSqlMIPrepare, execSql))

task('restore', shell(runSqlPrefix + ' < db.sql'))
task('restore-rows', shell(runSqlPrefix + ' < db-rows.sql'))
task('db-init', series('restore',
    shell('cat db-init.sql | grep INSERT | ' + runSqlPrefix)))

